package com.fjwt.gz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fjwt.gz.components.mq.constant.WebSocketConstants;
import com.fjwt.gz.components.mq.websocket.server.PCWsChannelServer;
import com.fjwt.gz.components.oss.model.OssFileConfig;
import com.fjwt.gz.core.constants.Constants;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.core.model.ApiRes;
import com.fjwt.gz.core.model.security.GzUserDetails;
import com.fjwt.gz.db.dto.AwardEmployeeDTO;
import com.fjwt.gz.db.dto.EmployeeDistributeDTO;
import com.fjwt.gz.db.entity.*;
import com.fjwt.gz.db.vo.AwardEmployeeVO;
import com.fjwt.gz.service.mapper.AgentEmployeeMapper;
import com.fjwt.gz.service.mapper.AwardEmployeeMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 机构员工活动渠道表 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-04-09
 */
@Slf4j
@Service
public class AwardEmployeeService extends ServiceImpl<AwardEmployeeMapper, AwardEmployeeEntity> {


    @Resource
    private AwardEmployeeMapper awardEmployeeMapper;

    @Autowired
    private AgentEmployeeMapper agentEmployeeMapper;

    @Autowired
    private OssRecordService ossRecordService;

    @Autowired
    private ActivityAwardService activityAwardService;

    @Autowired
    private AwardCouponService awardCouponService;

    @Autowired
    private AwardGoodsService awardGoodsService;

    @Autowired
    private AwardScoreService awardScoreService;

    @Autowired
    private AwardVirtualService awardVirtualService;

    @Autowired
    private PCWsChannelServer pcWsChannelServer;

    /**
     * 获取可派发员工列表
     *
     * @param iPage
     * @param employeeDTO
     * @return
     */
    public IPage<AwardEmployeeVO> getEmployeeDistributeList(IPage iPage, AwardEmployeeDTO employeeDTO) {
        return awardEmployeeMapper.getEmployeeDistributeList(iPage, employeeDTO);
    }


    /**
     * 卡券配置单个可派发人员
     *
     * @param employeeDTO
     */
    public void addOneEmployeeDistribute(AwardEmployeeDTO employeeDTO) {
        if (null == employeeDTO.getAwardId() || StringUtils.isEmpty(employeeDTO.getEmployeeNo())
                || null == employeeDTO.getAwardType() || null == employeeDTO.getIsChannelDisplay()) {
            throw new BizException("请求参数缺失！");
        }
        AgentEmployeeEntity entity = agentEmployeeMapper.selectOne(AgentEmployeeEntity.gw()
                .eq(AgentEmployeeEntity::getEmployeeNo, employeeDTO.getEmployeeNo()));
        if (null == entity) {
            throw new BizException("该人员信息不存在");
        }
        //判断该人员是否已添加
        AwardEmployeeEntity employeeEntity = awardEmployeeMapper.selectOne(AwardEmployeeEntity.gw()
                .eq(AwardEmployeeEntity::getAwardId, employeeDTO.getAwardId())
                .eq(AwardEmployeeEntity::getAwardType, employeeDTO.getAwardType())
                .eq(AwardEmployeeEntity::getAgentEmployeeId, entity.getAgentEmployeeId()));
        if (null != employeeEntity) {
            throw new BizException("该人员已配置！");
        }
        try {
            AwardEmployeeEntity dto = new AwardEmployeeEntity();
            dto.setAwardId(employeeDTO.getAwardId());
            dto.setAwardType(employeeDTO.getAwardType());
            dto.setAgentEmployeeId(entity.getAgentEmployeeId());
            dto.setIsChannelDisplay(employeeDTO.getIsChannelDisplay());
            awardEmployeeMapper.insert(dto);
        } catch (Exception e) {
            throw new BizException("该人员已配置！");
        }
    }

    /**
     * 批量导入配置可派发人员
     *
     * @param employeeDTO
     * @return
     */
    public void importBatchEmployeeDistributeByFile(AwardEmployeeDTO employeeDTO) {
        Long awardId = employeeDTO.getAwardId();
        String url = employeeDTO.getUrl();
        Integer awardType = employeeDTO.getAwardType();

        if (null == awardId || StrUtil.isBlank(url) || awardType == null) {
            throw new BizException("请求参数失败！");
        }

        List<EmployeeDistributeDTO> list;
        try {
            list = this.getEmployeeDestroyToList(url);
        } catch (Exception e) {
            log.error("文件读取失败，url: {}", url, e);
            throw new BizException("文件读取失败，请检查文件格式！");
        }

        if (CollUtil.isEmpty(list)) {
            throw new BizException("未找到人员名单文件！");
        }

        List<String> employeeNoList = list.stream()
                .map(EmployeeDistributeDTO::getEmployeeNo)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        if (CollUtil.isEmpty(employeeNoList)) {
            throw new BizException("员工编号为空！");
        }

        // 查询员工信息
        List<AgentEmployeeEntity> agentEmployeeEntities = agentEmployeeMapper.selectList(AgentEmployeeEntity.gw()
                .in(AgentEmployeeEntity::getEmployeeNo, employeeNoList));
        log.info("查询到 {} 个员工信息", agentEmployeeEntities.size());

        if (agentEmployeeEntities.isEmpty()) {
            throw new BizException("未查询到人员名单！请核实员所有工编号！");
        }

        Map<String, AgentEmployeeEntity> existingEmployeesMap = agentEmployeeEntities.stream()
                .collect(Collectors.toMap(AgentEmployeeEntity::getEmployeeNo, Function.identity()));

        Set<Long> agentEmployeeIdSet = existingEmployeesMap.values().stream()
                .map(AgentEmployeeEntity::getAgentEmployeeId)
                .collect(Collectors.toSet());

        // 查询已配置的奖品员工
        List<AwardEmployeeEntity> awardEmployeeEntities = awardEmployeeMapper.selectList(AwardEmployeeEntity.gw()
                .eq(AwardEmployeeEntity::getAwardId, awardId)
                .eq(AwardEmployeeEntity::getAwardType, awardType)
                .in(AwardEmployeeEntity::getAgentEmployeeId, agentEmployeeIdSet));
        log.info("查询到 {} 个已配置员工", awardEmployeeEntities.size());

        Set<Long> existingEmployeeIds = awardEmployeeEntities.stream()
                .map(AwardEmployeeEntity::getAgentEmployeeId)
                .collect(Collectors.toSet());

        final String IS_CHANNEL_DISPLAY_YES = "是";
        List<AwardEmployeeEntity> exportList = new ArrayList<>();
        for (EmployeeDistributeDTO dto : list) {
            String employeeNo = dto.getEmployeeNo();
            AgentEmployeeEntity agentEmployee = existingEmployeesMap.get(employeeNo);
            if (agentEmployee == null) continue;

            Long agentEmployeeId = agentEmployee.getAgentEmployeeId();
            if (existingEmployeeIds.contains(agentEmployeeId)) continue;

            exportList.add(new AwardEmployeeEntity()
                    .setAwardId(awardId)
                    .setAwardType(awardType)
                    .setAgentEmployeeId(agentEmployeeId)
                    .setIsChannelDisplay(IS_CHANNEL_DISPLAY_YES.equals(dto.getIsChannelDisplayVal()) ? 1 : 0));
        }

        if (exportList.isEmpty()) {
            throw new BizException("请核实员工编号！");
        }
//        for (int i = 0; i < list.size(); i++) {
//            String employeeNo = list.get(i).getEmployeeNo();
//            if (!existingEmployeesMap.containsKey(employeeNo)){
//                pcWsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), list.size(), "导入文档", "第" + (i + 1) + "行，人员编号不存在！", WebSocketConstants.ImportStatus.FAIL);
//                continue;
//            }
//
////            Long agentEmployeeId = agentEmployee.getAgentEmployeeId();
////            if (existingEmployeeIds.contains(agentEmployeeId)) continue;
//
//            exportList.add(new AwardEmployeeEntity()
//                    .setAwardId(awardId)
//                    .setAwardType(awardType)
//                    .setAgentEmployeeId(existingEmployeesMap.get(employeeNo).getAgentEmployeeId())
//                    .setIsChannelDisplay(IS_CHANNEL_DISPLAY_YES.equals(list.get(i).getIsChannelDisplayVal()) ? 1 : 0));
//        }

        try {
            if (CollUtil.isNotEmpty(exportList)) {
                awardEmployeeMapper.saveEmployeeList(exportList);
                log.info("成功插入 {} 条记录", exportList.size());
            }
        } catch (Exception e) {
            log.error("批量插入失败，exportList: {}", exportList, e);
            throw new BizException("操作失败！");
        }
    }


    /**
     * 通过导入文件获取可派发人员列表
     *
     * @return
     */
    public List<EmployeeDistributeDTO> getEmployeeDestroyToList(String ossFileUrl) {
        File file = FileUtil.file(String.format("./temp/%s.xlsx", DateUtil.date().getTime()));
        HttpUtil.downloadFile(ossFileUrl, file);

        // 添加oos上传记录
        OssRecordEntity ossRecordEntity = new OssRecordEntity();
        ossRecordEntity.setBizType(OssFileConfig.BIZ_TYPE.UPLOAD);
        ossRecordEntity.setOssUrl(ossFileUrl);
        ossRecordEntity.setFileSize(file.length());
        ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.COUPON_MCH_TYPE);
        ossRecordEntity.setSysUserId(GzUserDetails.getCurrentUserDetails().getSysUser().getSysUserId());
        ossRecordEntity.setCreatedAt(new Date());
        ossRecordService.save(ossRecordEntity);

        // 读取文件内容
        ExcelReader reader = ExcelUtil.getReader(file);
        reader.addHeaderAlias("人员编号", "employeeNo");
        reader.addHeaderAlias("渠道码是否可见", "isChannelDisplayVal");
        List<EmployeeDistributeDTO> resultList = reader.readAll(EmployeeDistributeDTO.class);
        reader.close();
        FileUtil.del(file);
        return resultList;
    }

    /**
     * 删除奖品所有可派发人员
     *
     * @param awardId   奖品id
     * @param awardType
     */
    public void removeAllAllocationUserByAwardId(Long awardId, Integer awardType) {
        if (null == awardId || null == awardType) {
            throw new BizException("请求参数缺失！");
        }

        List<ActivityAwardEntity> list = activityAwardService.list(ActivityAwardEntity.gw()
                .eq(ActivityAwardEntity::getAwardId, awardId)
                .eq(ActivityAwardEntity::getAwardType, awardType));
        if (!list.isEmpty()) {
            throw new BizException("该奖品已配置活动，不能删除！");
        }

        Integer awardState;
        switch (awardType) {
            case Constants.AWARD.COUPON:
                AwardCouponEntity couponEntity = awardCouponService.getById(awardId);
                if (couponEntity == null) {
                    throw new BizException("所对应奖品不存在，无法删除！");
                }
                awardState = couponEntity.getState();
                break;
            case Constants.AWARD.GOODS:
                AwardGoodsEntity goodsEntity = awardGoodsService.getById(awardId);
                if (goodsEntity == null) {
                    throw new BizException("所对应奖品不存在，无法删除！");
                }
                awardState = goodsEntity.getState();
                break;
            case Constants.AWARD.SCORE:
                AwardScoreEntity scoreEntity = awardScoreService.getById(awardId);
                if (scoreEntity == null) {
                    throw new BizException("所对应奖品不存在，无法删除！");
                }
                awardState = scoreEntity.getState();
                break;
            case Constants.AWARD.VIRTUAL_COUPON:
                AwardVirtualEntity virtualEntity = awardVirtualService.getById(awardId);
                if (virtualEntity == null) {
                    throw new BizException("所对应奖品不存在，无法删除！");
                }
                awardState = virtualEntity.getState();
                break;
            default:
                throw new BizException("无效的奖品类型，无法删除！");
        }

        if (awardState == Constants.AWARD_STATE.ONLINE) {
            throw new BizException("该奖品为上线状态，不能删除！");
        }

        LambdaQueryWrapper<AwardEmployeeEntity> removeWrapper = AwardEmployeeEntity.gw();
        removeWrapper.eq(AwardEmployeeEntity::getAwardId, awardId);
        removeWrapper.eq(AwardEmployeeEntity::getAwardType, awardType);
        remove(removeWrapper);
    }

    /**
     * 更新员工渠道码是否可见
     *
     * @param employeeDTO
     */
    public void updateEmpChannelDisplay(AwardEmployeeDTO employeeDTO) {
        if (employeeDTO.getAwardEmployeeId() == null || employeeDTO.getIsChannelDisplay() == null) {
            throw new BizException("请求参数异常！");
        }
        AwardEmployeeEntity employeeEntity = getById(employeeDTO.getAwardEmployeeId());
        if (employeeEntity == null) {
            throw new BizException("该记录不存在！");
        }
        employeeEntity.setIsChannelDisplay(employeeDTO.getIsChannelDisplay());
        updateById(employeeEntity);
    }
}
